package com.icss.flow.handler;

import com.icss.flow.common.CommonConstant;
import com.icss.flow.exception.CommonException;
import com.icss.flow.exception.FlowException;
import org.camunda.bpm.engine.ParseException;
import com.icss.flow.utils.HttpUtils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import lombok.extern.slf4j.Slf4j;
import org.camunda.bpm.engine.exception.NullValueException;
import org.dromara.common.core.domain.R;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import java.util.HashMap;
import java.util.stream.Collectors;


/**
 * @author Administrator
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(BindException.class)
    public R<?> bindExceptionHandler(BindException e) {
        String message = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining("、"));
        return R.fail(message);

    }


    //处理请求参数格式错误 @RequestParam上validate失败后抛出的异常是javax.validation.ConstraintViolationException

    @ExceptionHandler(ConstraintViolationException.class)
    public R<?> constraintViolationExceptionHandler(ConstraintViolationException e) {
        String message = e.getConstraintViolations().stream().map(ConstraintViolation::getMessage).collect(Collectors.joining("、"));
        return R.fail(message);
    }

    //处理请求参数格式错误 @RequestBody上validate失败后抛出的异常是MethodArgumentNotValidException异常。
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public R<?> handle1(MethodArgumentNotValidException ex) {
        String message = ex.getBindingResult().getAllErrors().stream().map(ObjectError::getDefaultMessage).collect(Collectors.joining("、"));
        return R.fail(message);
    }


    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public R<?> exception(HttpServletRequest request, Exception e) {
        String remoteHost = HttpUtils.getRemoteHost(request);
        log.error("ip={},url={},error:{}", remoteHost, request.getRequestURI(), e.getMessage());
        log.error("全局异常信息 ex={}", e.getMessage());
        return R.fail("系统异常，请稍后重试");
    }


    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public R<?> httpRequestMethodNotSupportedException(HttpServletRequest request, Exception e) {
        String remoteHost = HttpUtils.getRemoteHost(request);
        log.error("ip={},url={},error:{}", remoteHost, request.getRequestURI(), e.getMessage());
        return R.fail(CommonConstant.METHOD_NOT_SUPPORT_405, "方法错误");
    }

    @ExceptionHandler(NoHandlerFoundException.class)
    public R<?> noHandlerFoundException(HttpServletRequest request, Exception e) {
        String remoteHost = HttpUtils.getRemoteHost(request);
        log.error("ip={},url={},error:{}", remoteHost, request.getRequestURI(), e.getMessage());
        log.error("全局异常信息 ex={}", e.getMessage());
        return R.fail(CommonConstant.SC_INTERNAL_NOT_FOUND_404, "资源未找到");
    }

    @ExceptionHandler(FlowException.class)
    @ResponseStatus(HttpStatus.OK)
    public R<?> flowException(HttpServletRequest request, Exception e) {
        return R.fail(600, e.getMessage());
    }
    @ExceptionHandler(ParseException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public R<?> parseException(HttpServletRequest request, Exception e) {
        String remoteHost = HttpUtils.getRemoteHost(request);
        log.error("ip={},url={},error:{}", remoteHost, request.getRequestURI(), e.getMessage());
        log.error("全局异常信息 ex={}", e.getMessage());
        return R.fail(HttpStatus.BAD_REQUEST.value(), e.getMessage());
    }

    @ExceptionHandler(CommonException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public R<?> commonException(HttpServletRequest request, Exception e) {
        String remoteHost = HttpUtils.getRemoteHost(request);
        log.error("ip={},url={},error:{}", remoteHost, request.getRequestURI(), e.getMessage());
        log.error("全局异常信息 ex={}", e.getMessage());
        return R.fail(HttpStatus.BAD_REQUEST.value(), e.getMessage());
    }

    @ExceptionHandler(NullValueException.class)
    @ResponseStatus(HttpStatus.OK)
    public R<?> nullValueException() {
        return R.ok(new HashMap<String, Object>() {{
            put("xml","");
        }});
    }

}
